def apply_async(func, args, *, callback):
    result = func(*args)
    callback(result)


def print_result(result):
    print('Got:', result)


def add(x, y):
    return x + y


# 回调函数访问其他变量或者特定环境的变量值
class ResultHandler:
    def __init__(self):
        self.sequence = 0

    def handdler(self, result):
        self.sequence += 1
        print('[{}] Got: {}'.format(self.sequence, result))


# 闭包实现回调函数访问特定环境的变量值
def make_result():
    sequence = 0

    def handler(result):
        nonlocal sequence  # nonlocal用于声明，修改嵌套作用域（enclosing 作用域，外层非全局作用域）中的变量
        sequence += 1
        print('[{}] Got: {}'.format(sequence, result))

    return handler


# 使用协程实现
def make_handler():
    sequence = 0
    while True:
        result = yield  # 走到这里暂停，等待send,只能通过next
        sequence += 1
        print('[{}] Got: {}'.format(sequence, result))


if __name__ == '__main__':
    apply_async(add, (2, 3), callback=print_result)
    r = ResultHandler()
    apply_async(add, (1, 2), callback=r.handdler)
    apply_async(add, ('hello', 'world'), callback=r.handdler)

    r1 = make_result()
    apply_async(add, ('r1', 'world'), callback=r1)
    apply_async(add, ('r1', 'world'), callback=r1)

    r2 = make_handler()
    next(r2)
    apply_async(add, ('r2', 'world'), callback=r2.send)
    apply_async(add, ('r2', 'world'), callback=r2.send)
